@wenathlan/saddle 2.0.6 → 2.0.150

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/Dockerfile +47 -21
  2. package/LICENSE +0 -0
  3. package/README.md +19 -3
  4. package/alternatives.ts +0 -0
  5. package/boards.json +2 -2
  6. package/compute.ts +4 -4
  7. package/cores.json +2 -2
  8. package/docker.config +3 -3
  9. package/docs/.gitkeep +0 -0
  10. package/docs/CONVERSA.txt +0 -0
  11. package/docs/actionrecorder.md +0 -0
  12. package/docs/actionsincident.md +0 -0
  13. package/docs/alternatives.md +0 -0
  14. package/docs/architecture-1.8.19.md +0 -0
  15. package/docs/architecture-1.8.19.mmd +0 -0
  16. package/docs/architecture-1.8.19.png +0 -0
  17. package/docs/architecture.md +3 -3
  18. package/docs/artifactavailability.md +0 -0
  19. package/docs/artifactresearch-1.8.9.md +0 -0
  20. package/docs/assets/architecture.svg +0 -0
  21. package/docs/assets/saddle-browser-trace.webp +0 -0
  22. package/docs/assets/saddle-hero-bridge.webp +0 -0
  23. package/docs/assets/saddle-mark.webp +0 -0
  24. package/docs/assets/saddle-runtime-map.webp +0 -0
  25. package/docs/assets/saddlemark.svg +0 -0
  26. package/docs/batches-1816-1820.md +0 -0
  27. package/docs/brancharchive-2026-08-18.md +0 -0
  28. package/docs/branchaudit.md +0 -0
  29. package/docs/browser.md +0 -0
  30. package/docs/capabilityreport.md +0 -0
  31. package/docs/comparativeaudit.md +0 -0
  32. package/docs/consolidation.md +0 -0
  33. package/docs/containerplatforms-1.8.17.md +0 -0
  34. package/docs/containerplatforms-2.1.0.md +73 -0
  35. package/docs/documentmap-1.8.12.md +0 -0
  36. package/docs/e2ugh-engine.md +0 -0
  37. package/docs/ecosystemplan.md +0 -0
  38. package/docs/enginearchitecture.md +0 -0
  39. package/docs/example-localjob.ts +0 -0
  40. package/docs/example-publicapi.ts +0 -0
  41. package/docs/extension.md +0 -0
  42. package/docs/featureaudit.md +0 -0
  43. package/docs/flatbuildresearch-1.8.11.md +0 -0
  44. package/docs/gapmatrix.md +0 -0
  45. package/docs/hardware.md +0 -0
  46. package/docs/libraryapi.md +0 -0
  47. package/docs/licenseaudit-1.8.12.md +0 -0
  48. package/docs/logs/examplesession.json +54 -0
  49. package/docs/memoryengine.md +0 -0
  50. package/docs/mobileconversionresearch-1.8.10.md +0 -0
  51. package/docs/modes.md +0 -0
  52. package/docs/native-wrappers.md +38 -0
  53. package/docs/nativeidentityresearch-1.8.11.md +0 -0
  54. package/docs/optimization.md +0 -0
  55. package/docs/packageaudit185.md +0 -0
  56. package/docs/performance.md +0 -0
  57. package/docs/planning.1.8.18.md +0 -0
  58. package/docs/planning.1.8.19.md +0 -0
  59. package/docs/planning.engine.md +186 -0
  60. package/docs/platformpipelineaudit.md +0 -0
  61. package/docs/platformpipelines.md +0 -0
  62. package/docs/productindex.md +0 -0
  63. package/docs/registryresearch.md +0 -0
  64. package/docs/release.md +0 -0
  65. package/docs/release17notes.md +0 -0
  66. package/docs/release181notes.md +0 -0
  67. package/docs/release182notes.md +0 -0
  68. package/docs/release184notes.md +0 -0
  69. package/docs/release185notes.md +0 -0
  70. package/docs/release18notes.md +0 -0
  71. package/docs/releaseassets.md +0 -0
  72. package/docs/releasenotes-1.8.12.md +0 -0
  73. package/docs/releasenotes-1.8.13.md +0 -0
  74. package/docs/releasenotes-1.8.14.md +0 -0
  75. package/docs/releasenotes-1.8.15.md +0 -0
  76. package/docs/releasenotes-1.8.16.md +0 -0
  77. package/docs/releasenotes-1.8.17.md +0 -0
  78. package/docs/releasenotes-1.8.18.md +0 -0
  79. package/docs/releasenotes-1.8.19.md +0 -0
  80. package/docs/reorganization-1.8.8.md +0 -0
  81. package/docs/reorganization-1.8.9.md +0 -0
  82. package/docs/repo-analysis-1.8.21.json +0 -0
  83. package/docs/repo-candidates-1.8.21.jsonl +0 -0
  84. package/docs/repo-research-1.8.16.md +0 -0
  85. package/docs/repo-research-1.8.21.md +0 -0
  86. package/docs/repo-selected-1.8.21.json +0 -0
  87. package/docs/repo-synthesis-1.8.16.md +0 -0
  88. package/docs/repo-synthesis-1.8.21.md +0 -0
  89. package/docs/research-1.8.18-isolation.md +0 -0
  90. package/docs/research-1.8.19-virtual-browser.md +0 -0
  91. package/docs/roadmapp2p3.md +0 -0
  92. package/docs/s3compatible.md +0 -0
  93. package/docs/saddle.archive.1.8.17.tar.gz.gpg +0 -0
  94. package/docs/scanningresearch-1.8.11.md +0 -0
  95. package/docs/security.md +0 -0
  96. package/docs/securityaudit-1.8.7.md +0 -0
  97. package/docs/securityreferences-1.8.11.md +0 -0
  98. package/docs/securityresearch-1.8.11.md +0 -0
  99. package/docs/signingresearch-1.8.12.md +0 -0
  100. package/docs/signingwithoutcertificates.md +0 -0
  101. package/docs/signpathapplication.md +0 -0
  102. package/docs/sitemap.md +0 -0
  103. package/docs/tauri-glib-risk-1.8.11.md +0 -0
  104. package/docs/todo-1.8.15.md +0 -0
  105. package/docs/todo-1.8.16.md +0 -0
  106. package/docs/todo-1.8.18.md +0 -0
  107. package/docs/todo-1.8.19.md +0 -0
  108. package/docs/todo.md +0 -0
  109. package/docs/toolchainresearch-1.8.9.md +0 -0
  110. package/docs/toolchains.md +0 -0
  111. package/docs/usage.md +0 -0
  112. package/docs/viability.md +0 -0
  113. package/docs/virtualization.md +0 -0
  114. package/docs/web-duplicatecleanup.md +0 -0
  115. package/docs/web-ideas.md +0 -0
  116. package/docs/workflowimprovements-2026-08-19.md +0 -0
  117. package/docs/workflowinputs.md +0 -0
  118. package/docs/workflowoperations.md +0 -0
  119. package/gpumonitor.cpp +0 -0
  120. package/gpus.json +1 -1
  121. package/index.ts +14 -15
  122. package/manifest.json +20 -0
  123. package/media.ts +0 -0
  124. package/mttg.config +1 -1
  125. package/orchestrator.ts +5 -2
  126. package/package.json +142 -91
  127. package/passage.config +2 -2
  128. package/performance.ts +0 -0
  129. package/processors.json +1 -1
  130. package/qemu.config +2 -2
  131. package/qemubridge.py +0 -0
  132. package/quantum.ts +0 -0
  133. package/render.ts +0 -0
  134. package/scheduler.ts +0 -0
  135. package/security.ts +0 -0
  136. package/tiers.ts +9 -3
  137. package/tsconfig.json +22 -17
  138. package/virtualcpu.ts +1 -0
  139. package/virtualgpu.ts +1 -0
  140. package/virtualhardware.c +0 -0
  141. package/virtualhardware.json +2 -2
  142. package/virtualization.ts +0 -0
  143. package/virtualizationcore.cpp +0 -0
  144. package/virtualmemory.ts +0 -0
  145. package/vm.config.json +3 -3
  146. package/biome.json +0 -153
  147. package/dist/acquisition.d.ts +0 -359
  148. package/dist/acquisition.d.ts.map +0 -1
  149. package/dist/acquisition.js +0 -629
  150. package/dist/acquisition.js.map +0 -1
  151. package/dist/alternatives.d.ts +0 -509
  152. package/dist/alternatives.d.ts.map +0 -1
  153. package/dist/alternatives.js +0 -951
  154. package/dist/alternatives.js.map +0 -1
  155. package/dist/automation.d.ts +0 -426
  156. package/dist/automation.d.ts.map +0 -1
  157. package/dist/automation.js +0 -561
  158. package/dist/automation.js.map +0 -1
  159. package/dist/browser.d.ts +0 -562
  160. package/dist/browser.d.ts.map +0 -1
  161. package/dist/browser.js +0 -1057
  162. package/dist/browser.js.map +0 -1
  163. package/dist/capacitor.config.d.ts +0 -13
  164. package/dist/capacitor.config.d.ts.map +0 -1
  165. package/dist/capacitor.config.js +0 -26
  166. package/dist/capacitor.config.js.map +0 -1
  167. package/dist/cli.d.ts +0 -17
  168. package/dist/cli.d.ts.map +0 -1
  169. package/dist/cli.js +0 -111
  170. package/dist/cli.js.map +0 -1
  171. package/dist/communication.d.ts +0 -192
  172. package/dist/communication.d.ts.map +0 -1
  173. package/dist/communication.js +0 -418
  174. package/dist/communication.js.map +0 -1
  175. package/dist/compute.d.ts +0 -1161
  176. package/dist/compute.d.ts.map +0 -1
  177. package/dist/compute.js +0 -2273
  178. package/dist/compute.js.map +0 -1
  179. package/dist/distribution.d.ts +0 -529
  180. package/dist/distribution.d.ts.map +0 -1
  181. package/dist/distribution.js +0 -811
  182. package/dist/distribution.js.map +0 -1
  183. package/dist/execution.d.ts +0 -530
  184. package/dist/execution.d.ts.map +0 -1
  185. package/dist/execution.js +0 -761
  186. package/dist/execution.js.map +0 -1
  187. package/dist/format.d.ts +0 -19
  188. package/dist/format.d.ts.map +0 -1
  189. package/dist/format.js +0 -60
  190. package/dist/format.js.map +0 -1
  191. package/dist/foundation.d.ts +0 -176
  192. package/dist/foundation.d.ts.map +0 -1
  193. package/dist/foundation.js +0 -309
  194. package/dist/foundation.js.map +0 -1
  195. package/dist/index.d.ts +0 -735
  196. package/dist/index.d.ts.map +0 -1
  197. package/dist/index.js +0 -1020
  198. package/dist/index.js.map +0 -1
  199. package/dist/integration.d.ts +0 -236
  200. package/dist/integration.d.ts.map +0 -1
  201. package/dist/integration.js +0 -236
  202. package/dist/integration.js.map +0 -1
  203. package/dist/intelligence.d.ts +0 -94
  204. package/dist/intelligence.d.ts.map +0 -1
  205. package/dist/intelligence.js +0 -145
  206. package/dist/intelligence.js.map +0 -1
  207. package/dist/isolation.d.ts +0 -129
  208. package/dist/isolation.d.ts.map +0 -1
  209. package/dist/isolation.js +0 -96
  210. package/dist/isolation.js.map +0 -1
  211. package/dist/media.d.ts +0 -344
  212. package/dist/media.d.ts.map +0 -1
  213. package/dist/media.js +0 -986
  214. package/dist/media.js.map +0 -1
  215. package/dist/modes.d.ts +0 -359
  216. package/dist/modes.d.ts.map +0 -1
  217. package/dist/modes.js +0 -134
  218. package/dist/modes.js.map +0 -1
  219. package/dist/operations.d.ts +0 -67
  220. package/dist/operations.d.ts.map +0 -1
  221. package/dist/operations.js +0 -94
  222. package/dist/operations.js.map +0 -1
  223. package/dist/orchestrator.d.ts +0 -1339
  224. package/dist/orchestrator.d.ts.map +0 -1
  225. package/dist/orchestrator.js +0 -4308
  226. package/dist/orchestrator.js.map +0 -1
  227. package/dist/packager/targetcli.js +0 -4
  228. package/dist/performance.d.ts +0 -416
  229. package/dist/performance.d.ts.map +0 -1
  230. package/dist/performance.js +0 -827
  231. package/dist/performance.js.map +0 -1
  232. package/dist/quantum.d.ts +0 -810
  233. package/dist/quantum.d.ts.map +0 -1
  234. package/dist/quantum.js +0 -2073
  235. package/dist/quantum.js.map +0 -1
  236. package/dist/render.d.ts +0 -381
  237. package/dist/render.d.ts.map +0 -1
  238. package/dist/render.js +0 -1073
  239. package/dist/render.js.map +0 -1
  240. package/dist/scheduler.d.ts +0 -596
  241. package/dist/scheduler.d.ts.map +0 -1
  242. package/dist/scheduler.js +0 -1259
  243. package/dist/scheduler.js.map +0 -1
  244. package/dist/security.d.ts +0 -501
  245. package/dist/security.d.ts.map +0 -1
  246. package/dist/security.js +0 -1170
  247. package/dist/security.js.map +0 -1
  248. package/dist/server.d.ts +0 -21
  249. package/dist/server.d.ts.map +0 -1
  250. package/dist/server.js +0 -52
  251. package/dist/server.js.map +0 -1
  252. package/dist/tiers.d.ts +0 -1002
  253. package/dist/tiers.d.ts.map +0 -1
  254. package/dist/tiers.js +0 -2165
  255. package/dist/tiers.js.map +0 -1
  256. package/dist/virtual.d.ts +0 -641
  257. package/dist/virtual.d.ts.map +0 -1
  258. package/dist/virtual.js +0 -1285
  259. package/dist/virtual.js.map +0 -1
  260. package/dist/virtualcpu.d.ts +0 -316
  261. package/dist/virtualcpu.d.ts.map +0 -1
  262. package/dist/virtualcpu.js +0 -1180
  263. package/dist/virtualcpu.js.map +0 -1
  264. package/dist/virtualgpu.d.ts +0 -345
  265. package/dist/virtualgpu.d.ts.map +0 -1
  266. package/dist/virtualgpu.js +0 -1000
  267. package/dist/virtualgpu.js.map +0 -1
  268. package/dist/virtualization.d.ts +0 -607
  269. package/dist/virtualization.d.ts.map +0 -1
  270. package/dist/virtualization.js +0 -1187
  271. package/dist/virtualization.js.map +0 -1
  272. package/dist/virtualmemory.d.ts +0 -818
  273. package/dist/virtualmemory.d.ts.map +0 -1
  274. package/dist/virtualmemory.js +0 -1796
  275. package/dist/virtualmemory.js.map +0 -1
  276. package/dist/webscrape.d.ts +0 -720
  277. package/dist/webscrape.d.ts.map +0 -1
  278. package/dist/webscrape.js +0 -2697
  279. package/dist/webscrape.js.map +0 -1
  280. package/web/extension/manifest.json +0 -23
  281. package/web/readme.md +0 -382
  282. package/web/tsconfig.json +0 -25
package/Dockerfile CHANGED
@@ -10,7 +10,10 @@
10
10
  # stages at the end of this file, folded from the former
11
11
  # dockerfile.saddle) — an explicit build target
12
12
  # (`docker build --target saddle-runtime .`), the node 26 storage and
13
- # compute service published as ghcr.io/wenathlan/saddle:<version>.
13
+ # compute service published as ghcr.io/wenathlan/saddle:<version>
14
+ # across the four-arch family standard (amd64, arm64, ppc64le, s390x
15
+ # — the trixie slim base line; the stage also builds the web SPA so
16
+ # the image serves the self-hosted console via `node /app/web/server.ts`).
14
17
  #
15
18
  # saddle v2 (grand merge) - virtual hardware engine, multi-stage, multi-arch image.
16
19
  #
@@ -91,7 +94,7 @@
91
94
  # -v vmdata:/data/vmdata -v webdata:/data/web \
92
95
  # -v ./vm.config.json:/engine/vm.config.json:ro \
93
96
  # -e PORT=8080 -e NODE_ENV=production -p 31280:8080 \
94
- # ghcr.io/wenathlan/saddle:vhe-2.0.6
97
+ # ghcr.io/wenathlan/saddle:vhe-2.1.6
95
98
  #
96
99
  # vheqemu (the guest runner; build it first with
97
100
  # docker build --target qemu-runtime -t saddle/qemu:11.1.0 . because the
@@ -125,7 +128,7 @@
125
128
  # -e VHE_GPU_PROFILE=b200 -e VHE_GPUS=8 -e VHE_MIG=1 \
126
129
  # -e VHE_SMI_DRIVER=575.57.08 -e VHE_SMI_CUDA=12.9 \
127
130
  # -e VHE_SMI_INTERVAL=30 -e VHE_SKIP_XVFB=1 -e VHE_SKIP_VALIDATE=1 \
128
- # ghcr.io/wenathlan/saddle:vhe-2.0.6 /bin/bash -c '
131
+ # ghcr.io/wenathlan/saddle:vhe-2.1.6 /bin/bash -c '
129
132
  # while true; do
130
133
  # /usr/local/bin/nvidia-smi "$VHE_GPU_PROFILE" "$VHE_GPUS" || true
131
134
  # sleep "$VHE_SMI_INTERVAL"
@@ -142,7 +145,7 @@
142
145
  # -v qemudata:/data/qemudata \
143
146
  # -v ./qemubridge.py:/engine/qemubridge.py:ro \
144
147
  # -e QMP_SOCKET=/run/vhe/vm.qmp -e PYTHONUNBUFFERED=1 \
145
- # ghcr.io/wenathlan/saddle:vhe-2.0.6 \
148
+ # ghcr.io/wenathlan/saddle:vhe-2.1.6 \
146
149
  # python3 /engine/qemubridge.py --socket /run/vhe/vm.qmp status
147
150
  #
148
151
  # saddle-node (the node-engine service, the former compose.yml
@@ -156,7 +159,7 @@
156
159
  # --log-driver json-file --log-opt max-size=50m --log-opt max-file=5 \
157
160
  # --tmpfs /tmp:size=2g,mode=1777 \
158
161
  # -e SADDLE_MEMORY_ENGINE=ram -e SBOT_PLATFORM= -e SBOT_CDN_URL= \
159
- # ghcr.io/wenathlan/saddle:2.0.6 \
162
+ # ghcr.io/wenathlan/saddle:2.1.6 \
160
163
  # node dist/cli.js plan
161
164
  #
162
165
  # observability (the former prometheus scraper of the full profile)
@@ -636,6 +639,32 @@ ENTRYPOINT ["/usr/bin/tini", "--", "qemu-system-x86_64"]
636
639
  # ---------------------------------------------------------------------------
637
640
  # stage 5: runtime (final, default target, the vhe/vhegpu docker run recipes)
638
641
  # ---------------------------------------------------------------------------
642
+ # saddle-build: the node-engine build stage (defined here, before the
643
+ # vhe runtime, so BOTH container surfaces can consume its output: the
644
+ # vhe runtime copies the built web SPA for its /engine/web console and
645
+ # the saddle-runtime stage copies the engine dist plus the same web
646
+ # tree - one build, two consumers). The stage runs native (never under
647
+ # QEMU): its outputs are platform-independent static/js payloads.
648
+
649
+ # the build stage pins to the native build platform ($BUILDPLATFORM): its
650
+ # outputs (the engine dist, pure js, and the web SPA, static assets) are
651
+ # architecture-independent, while the tailwind/lightningcss pipeline only
652
+ # ships native bindings for the builder platforms - the per-arch legs never
653
+ # run it under QEMU.
654
+ FROM --platform=$BUILDPLATFORM node:26.8.1-slim@sha256:c0753125a3789977aefe869cbebccf70e3cfd7ea84ca48547458f02e4f1d7146 AS saddle-build
655
+
656
+ ARG SADDLE_VERSION
657
+ WORKDIR /app
658
+
659
+ ENV NPM_CONFIG_LEGACY_PEER_DEPS=true
660
+
661
+ COPY package.json package-lock.json ./
662
+ RUN npm ci --ignore-scripts --legacy-peer-deps
663
+ COPY . .
664
+ RUN npm run build:engine \
665
+ && node --check dist/cli.js \
666
+ && npm run web:build:pages
667
+
639
668
  FROM ${UBUNTU} AS runtime
640
669
  ARG TARGETARCH
641
670
  ARG NODE_VERSION
@@ -873,8 +902,12 @@ COPY qemu.config mttg.config passage.config docker.config /engine/
873
902
  # the web node ships inside the main container: the mesh edition (auth,
874
903
  # sqlite database, dashboard and the browser sandbox pages) runs from the
875
904
  # same image, so one container serves the engine AND the web surface.
876
- # run it with: docker run ghcr.io/wenathlan/saddle node /engine/web/server.js
905
+ # run it with: docker run ghcr.io/wenathlan/saddle node /engine/web/server.ts
877
906
  COPY web /engine/web
907
+ # the built web SPA (vite, from the saddle-build stage): the console
908
+ # server (node /engine/web/server.ts) serves web/dist/public - the
909
+ # unified React interface that absorbed the former static pages.
910
+ COPY --from=saddle-build /app/web/dist /engine/web/dist
878
911
 
879
912
  RUN set -eux; \
880
913
  chmod 0755 /usr/local/bin/nvidia-smi /usr/local/bin/aetherforge; \
@@ -1238,7 +1271,7 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --start-interval=5s
1238
1271
  # OCI labels for registry introspection.
1239
1272
  LABEL org.opencontainers.image.title="saddle virtual-hardware engine (the grand merge)" \
1240
1273
  org.opencontainers.image.description="100% software virtual hardware: per-profile CPU/memory spoofing via LD_PRELOAD (max/balanced/lite), mesa 26.2.1 llvmpipe/lavapipe/rusticl, QEMU 11.1.0 TCG/MTTCG, virtual nvidia-smi adapter + NVML/CUDA shims, node 26.7.0, python bridge" \
1241
- org.opencontainers.image.version="2.0.6" \
1274
+ org.opencontainers.image.version="2.1.6" \
1242
1275
  org.opencontainers.image.licenses="MIT" \
1243
1276
  org.opencontainers.image.source="https://github.com/wenathlan/saddle" \
1244
1277
  org.opencontainers.image.documentation="https://github.com/wenathlan/saddle/blob/main/README.md" \
@@ -1277,20 +1310,7 @@ ENTRYPOINT ["/entrypoint.sh"]
1277
1310
  # docker build --target saddle-runtime -t saddle:<version> .
1278
1311
  # ══════════════════════════════════════════════════════════════════════
1279
1312
 
1280
- FROM node:26.8.1-bookworm-slim AS saddle-build
1281
-
1282
- ARG SADDLE_VERSION
1283
- WORKDIR /app
1284
-
1285
- ENV NPM_CONFIG_LEGACY_PEER_DEPS=true
1286
-
1287
- COPY package.json package-lock.json ./
1288
- RUN npm ci --ignore-scripts --legacy-peer-deps
1289
- COPY . .
1290
- RUN npm run build:engine \
1291
- && node --check dist/cli.js
1292
-
1293
- FROM node:26.8.1-bookworm-slim AS saddle-runtime
1313
+ FROM node:26.8.1-slim@sha256:c0753125a3789977aefe869cbebccf70e3cfd7ea84ca48547458f02e4f1d7146 AS saddle-runtime
1294
1314
 
1295
1315
  ARG SADDLE_VERSION
1296
1316
  LABEL org.opencontainers.image.title="Saddle" \
@@ -1337,6 +1357,12 @@ RUN apt-get update \
1337
1357
  && rm -rf node_modules/cpu-features/deps \
1338
1358
  && find node_modules -type f -name Dockerfile -delete
1339
1359
  COPY --from=saddle-build /app/dist ./dist
1360
+ # the web service surface (self-hosted console): the built SPA
1361
+ # (web/dist/public from the saddle-build vite run) plus the pure-node
1362
+ # server stack (server.ts, db.ts, auth.ts, mesh.ts, sandbox.ts,
1363
+ # mime.types, init.sql, schema.prisma) - zero npm dependencies, the
1364
+ # node 26 runtime carries everything (node:sqlite, node:crypto).
1365
+ COPY --from=saddle-build /app/web ./web
1340
1366
 
1341
1367
  USER node
1342
1368
 
package/LICENSE CHANGED
File without changes
package/README.md CHANGED
@@ -30,7 +30,9 @@ domain modules land beside the saddle domains:
30
30
  | `scheduler.ts`, `compute.ts`, `performance.ts` | job queues, batch compute and benchmark planning |
31
31
  | `media.ts`, `render.ts`, `quantum.ts`, `tiers.ts` | media pipeline, GPU registry, quantum simulation, tier policy |
32
32
  | `security.ts`, `alternatives.ts` | hardening gates and the alternative-stack catalog |
33
- | `web/` | the static console and the zero-dependency self-hosted API (`node web/server.js`) |
33
+ | `index.html`, `App.tsx`, `Sol/` | the single SPA shell and the Sol theme (one tsx app with one stylesheet per theme) |
34
+ | `server.ts`, `sandbox.ts` | the zero-dependency self-hosted API of the 2.0.150 grand-merge envelope (`node server.ts`; the api answers its version at `/api/v1/health`) and the browser-pure engine port |
35
+ | `vercel.json`, `netlify.toml` | the platform deploy adapters beside the surface they publish (the caddy ghost stays out of the tree) |
34
36
  | `specs/*` package exports | processors, gpus, cores, boards and the qemu/mttg/passage/docker envelopes |
35
37
 
36
38
  The full pre-merge documentation of the engine lives in
@@ -57,7 +59,7 @@ console.log(context.summary);
57
59
  The deterministic examples and tests do not require network access or real credentials:
58
60
 
59
61
  ```bash
60
- node --import tsx examples/publicapi.ts
62
+ node --import tsx docs/example-publicapi.ts
61
63
  npm test
62
64
  ```
63
65
 
@@ -232,7 +234,7 @@ npm run web:check
232
234
  VITE_BASE_PATH=/saddle npm run web:build:pages
233
235
  ```
234
236
 
235
- Small public configuration and visual assets live under `web/public/`. The development collector is TypeScript source at `web/lib/debugcollector.ts`, injected only in development, and uses `/debuglogs`; it is not part of the production build. The obsolete `web/public/__manus__` directory is intentionally absent.
237
+ Small public configuration and visual assets live under `web/public/`. The development collector is TypeScript source at `web/debugcollector.ts`, injected only in development, and uses `/debuglogs`; it is not part of the production build. The obsolete `web/public/__manus__` directory is intentionally absent.
236
238
 
237
239
  ## Development
238
240
 
@@ -300,3 +302,17 @@ Version 1.8.19 organizes the existing engine into twenty documented, dependency-
300
302
  ## License
301
303
 
302
304
  Saddle is distributed under the [GNU General Public License v3.0 only](LICENSE).
305
+
306
+ ---
307
+
308
+ # The Sol theme
309
+
310
+ # Saddle Sol
311
+
312
+ Saddle is the 20-modality sandbox platform of the DevThink family: one engine spanning compute, virtualization, media, mesh, automation and the other modalities, exposed as a self-hosted site. This Sol theme is the platform's web surface — a Vite + React SPA (console, dashboard, playground, integrations) served from the same sqlite database that `schema.prisma`, `init.sql` and `drizzle.config.ts` describe.
313
+
314
+ ```bash
315
+ pnpm install
316
+ pnpm dev
317
+ ```
318
+
package/alternatives.ts CHANGED
File without changes
package/boards.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "date": "2026-08-22",
8
8
  "dateFirstDoctrine": "The observer validates all specifications against the latest stable releases available on 2026-08-22.",
9
9
  "toolchain": {
10
- "node": "26.7.0 Current",
10
+ "node": "26.12.0 Current",
11
11
  "nodeAlt": "24.19.0 LTS",
12
12
  "typescript": "7.0.2",
13
13
  "python": "3.14.7",
@@ -88,7 +88,7 @@
88
88
  }
89
89
  },
90
90
  "name": "boards.json",
91
- "version": "2.0.0",
91
+ "version": "2.0.127",
92
92
  "title": "saddle - Virtual Motherboard Database (retail boards + platform reference sockets)",
93
93
  "sources": [
94
94
  "pool:boards.json [S6, 20 retail boards]",
package/compute.ts CHANGED
@@ -2554,7 +2554,7 @@ export function buildvmcrdmanifest(opts?: {
2554
2554
  'metadata:',
2555
2555
  ` name: ${plural}.${group}`,
2556
2556
  'spec:',
2557
- ' group: ' + group,
2557
+ ` group: ${group}`,
2558
2558
  ' scope: Namespaced',
2559
2559
  ' names:',
2560
2560
  ` plural: ${plural}`,
@@ -2562,7 +2562,7 @@ export function buildvmcrdmanifest(opts?: {
2562
2562
  ` kind: ${kind}`,
2563
2563
  ' shortNames: [vm, evm]',
2564
2564
  ' versions:',
2565
- ' - name: ' + version,
2565
+ ` - name: ${version}`,
2566
2566
  ' served: true',
2567
2567
  ' storage: true',
2568
2568
  ' subresources:',
@@ -2618,8 +2618,8 @@ export function buildvmcrdmanifest(opts?: {
2618
2618
  '',
2619
2619
  ].join('\n');
2620
2620
  const sample = [
2621
- 'apiVersion: ' + group + '/' + version,
2622
- 'kind: ' + kind,
2621
+ `apiVersion: ${group}/${version}`,
2622
+ `kind: ${kind}`,
2623
2623
  'metadata:',
2624
2624
  ' name: demo-vm',
2625
2625
  ' namespace: saddle',
package/cores.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "metadata": {
3
3
  "id": "cores.json",
4
- "version": "2.0.0",
4
+ "version": "2.0.127",
5
5
  "date": "2026-08-22",
6
6
  "datestamp": "2026-08-22T00:00:00Z",
7
7
  "observer": "third person observer notes the hybrid core inventory reflects production silicon as of 2026-08-22",
@@ -36,7 +36,7 @@
36
36
  ]
37
37
  },
38
38
  "stack": {
39
- "node": "26.7.0 Current",
39
+ "node": "26.12.0 Current",
40
40
  "nodeAlt": "24.19.0 LTS",
41
41
  "typescript": "7.0.2",
42
42
  "python": "3.14.7",
package/docker.config CHANGED
@@ -2,7 +2,7 @@
2
2
  "meta": {
3
3
  "name": "docker.config",
4
4
  "title": "saddle - Docker Engine and Containerization Configuration",
5
- "version": "2.0.0",
5
+ "version": "2.1.6",
6
6
  "date": "2026-08-22",
7
7
  "language": "en",
8
8
  "sources": [
@@ -618,7 +618,7 @@
618
618
  "labels": {
619
619
  "org.opencontainers.image.title": "saddle-v6",
620
620
  "org.opencontainers.image.description": "Saddle v6 virtualization orchestrator with QEMU 11.1.0, Node 22 LTS, Python 3.13.5, MTTG, Passage, OVMF",
621
- "org.opencontainers.image.version": "2.0.0",
621
+ "org.opencontainers.image.version": "2.1.6",
622
622
  "org.opencontainers.image.created": "2026-08-22T00:00:00Z",
623
623
  "org.opencontainers.image.authors": "Saddle Core <core@saddle.dev>",
624
624
  "org.opencontainers.image.url": "https://saddle.dev",
@@ -630,7 +630,7 @@
630
630
  "org.opencontainers.image.base.name": "debian:bookworm-slim",
631
631
  "org.opencontainers.image.base.digest": "sha256:bookworm-slim-pinned-2026-08-22",
632
632
  "saddle": {
633
- "com.saddle.version": "2.0.0",
633
+ "com.saddle.version": "2.1.6",
634
634
  "com.saddle.engine": "qemu-11.1.0",
635
635
  "com.saddle.modes": "32",
636
636
  "com.saddle.forge.mirrors": "github,gitea,forgejo",
package/docs/.gitkeep CHANGED
File without changes
package/docs/CONVERSA.txt CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -104,7 +104,7 @@ Line counts are the shipped files (v2 carryover plus the v3/v5/v6 additions); ev
104
104
  | `libs/gpumonitor.cpp` | 1543 | C++26 four-mode build: CLI smi-adapter, NVML/libcuda shim, N-API addon, forge mode (Plan/validate/qemu_argv, Mttg work-stealing mirror) | 12 hooks |
105
105
  | `libs/virtualhardware.c` | 1011 | C11 LD_PRELOAD core: open-family interception, vhe_translate, inotify regeneration thread, xorshift32 drift, constructor 101 | 12 hooks |
106
106
 
107
- Data files: `gpus.json` 2408, `processors.json` 2217, `vm.config.json` 1910, `cores.json` 1801, `mttg.config` 1548, `boards.json` 1517, `passage.config` 1330, `qemu.config` 1061, `virtualhardware.json` 739, `docker.config` 768. Web node (`web/`, the v6 edition plus the v7 wave): `sandbox.js` 1433 is the browser-pure engine port (bank, procfs payloads, the 89-char smi table, mesa summaries, boot dmesg and the command dispatcher), `server.js` 640 serves the console plus the `/api/v1` contract (health, spec catalogs, sandbox lifecycle, exec) over `node:http`, `index.html` 646 renders the spec panel, terminal and bus timeline, adapters `vercel.json`/`netlify.toml`/`caddyfile` (static edge, api reverse proxied) and `readme.md` 120; the v7 wave completes the node with `db.js` (sqlite persistence for users, sessions and sandboxes), `auth.js` (scrypt password hashing, timing-safe verification, cookie sessions), `mesh.js` (HMAC-SHA256 signed clone-to-main calls with replay windows), the `login.html`/`register.html`/`dashboard.html` pages, `package.json`/`Dockerfile` (image `ghcr.io/wenathlan/e2ugh (main image, web/ included)`; node pinned by the root `.nvmrc`), the database definition kept flat as `schema.prisma` plus `init.sql`, and `mime.types`. Total repository: about 62,200 lines across 83 tracked files (the v2 carryover plus the v3 domains, the v5 media/test waves and the v6 web edition; the `tests/` suite alone is 3,674 lines across eleven files).
107
+ Data files: `gpus.json` 2408, `processors.json` 2217, `vm.config.json` 1910, `cores.json` 1801, `mttg.config` 1548, `boards.json` 1517, `passage.config` 1330, `qemu.config` 1061, `virtualhardware.json` 739, `docker.config` 768. Web node (`web/`, the v6 edition plus the v7 wave): `sandbox.ts` 1433 is the browser-pure engine port (bank, procfs payloads, the 89-char smi table, mesa summaries, boot dmesg and the command dispatcher), `server.ts` 640 serves the console plus the `/api/v1` contract (health, spec catalogs, sandbox lifecycle, exec) over `node:http`, `index.html` 646 renders the spec panel, terminal and bus timeline, adapters `vercel.json`/`netlify.toml`/`caddyfile` (static edge, api reverse proxied) and `readme.md` 120; the v7 wave completes the node with `db.ts` (sqlite persistence for users, sessions and sandboxes), `auth.ts` (scrypt password hashing, timing-safe verification, cookie sessions), `mesh.ts` (HMAC-SHA256 signed clone-to-main calls with replay windows), the `login.html`/`register.html`/`dashboard.html` pages, `package.json`/`Dockerfile` (image `ghcr.io/wenathlan/e2ugh (main image, web/ included)`; node pinned by the root `.nvmrc`), the database definition kept flat as `schema.prisma` plus `init.sql`, and `mime.types`. Total repository: about 62,200 lines across 83 tracked files (the v2 carryover plus the v3 domains, the v5 media/test waves and the v6 web edition; the `tests/` suite alone is 3,674 lines across eleven files).
108
108
 
109
109
  ## 3a. v3 redistribution: features live in domains
110
110
 
@@ -129,7 +129,7 @@ Tests live in the `tests/` directory (one of the five allowed directories) and r
129
129
 
130
130
  ## 3c. Web node architecture (v7)
131
131
 
132
- The web node is a static edge plus one self-hosted process. Clones (Vercel and Netlify static deploys of the `web/` pages, redeployed from the `pages.yml` zip -9 bundle) ship only immutable assets: the console, the auth pages and `sandbox.js`, which runs the whole engine client-side and keeps working with no backend. The main node (`node web/server.js` behind the `caddyfile` on devthink.pro, packaged as `ghcr.io/wenathlan/e2ugh (main image, web/ included)`) owns everything stateful: `db.js` opens the sqlite file (`schema.prisma`/`init.sql` define it, kept flat per the two-level contract), `auth.js` is the auth authority - scrypt password hashing with per-user salts, timing-safe verification and server-side sessions delivered as `HttpOnly` cookies - and `mesh.js` verifies the HMAC-SHA256 signature (method, path, body digest, timestamp, bounded replay window) that every clone attaches to forwarded calls before routing. The design is deliberately anti-serverless: no function runs on the edge platforms, clones hold no secrets and no database, and unauthenticated clones receive 401 from the main node instead of any partial authority.
132
+ The web node is a static edge plus one self-hosted process. Clones (Vercel and Netlify static deploys of the `web/` pages, redeployed from the `pages.yml` zip -9 bundle) ship only immutable assets: the console, the auth pages and `sandbox.ts`, which runs the whole engine client-side and keeps working with no backend. The main node (`node web/server.ts` behind the `caddyfile` on devthink.pro, packaged as `ghcr.io/wenathlan/e2ugh (main image, web/ included)`) owns everything stateful: `db.ts` opens the sqlite file (`schema.prisma`/`init.sql` define it, kept flat per the two-level contract), `auth.ts` is the auth authority - scrypt password hashing with per-user salts, timing-safe verification and server-side sessions delivered as `HttpOnly` cookies - and `mesh.ts` verifies the HMAC-SHA256 signature (method, path, body digest, timestamp, bounded replay window) that every clone attaches to forwarded calls before routing. The design is deliberately anti-serverless: no function runs on the edge platforms, clones hold no secrets and no database, and unauthenticated clones receive 401 from the main node instead of any partial authority.
133
133
 
134
134
  ## 4. One bus, one state machine, one metrics store
135
135
 
@@ -209,7 +209,7 @@ Per-target delivery notes (one line each, from the collapsed topic docs):
209
209
  | Target | How the same library is consumed |
210
210
  | --- | --- |
211
211
  | desktop | EgUi lab UI over the in-process factory; every control honors the 44 px touch target |
212
- | web | browser bundle shipped as the `web/` console (v6): `sandbox.js` mirrors the verified bank, `server.js` serves it and `/api/spec`; zero dependencies keep the graph tree-shakeable |
212
+ | web | browser bundle shipped as the `web/` console (v6): `sandbox.ts` mirrors the verified bank, `server.ts` serves it and `/api/spec`; zero dependencies keep the graph tree-shakeable |
213
213
  | extension | browser extension service worker; endpoints bind a random port, never localhost |
214
214
  | cli | planner CLI: `node --experimental-strip-types index.ts` reading `vm.config.toml` |
215
215
  | android | container/wasm module surface through the JVM bridge; arm64 native runner images |
File without changes
File without changes
File without changes
Binary file
File without changes
File without changes
File without changes
File without changes
package/docs/browser.md CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,73 @@
1
+ # Container platform decision for 2.1.0
2
+
3
+ ## Scope
4
+
5
+ Version 2.1.0 expands the Saddle node-engine OCI image (the `saddle-runtime`
6
+ target of the one container file, published by the `publish ghcr` workflow)
7
+ from a three-platform Linux manifest index to the four-architecture family
8
+ surface: `linux/amd64`, `linux/arm64`, `linux/ppc64le`, and `linux/s390x`.
9
+ The selection unifies the container surfaces of the grand merge: the saddle
10
+ lineage shipped amd64/arm64/ppc64le (the 1.8.17 decision, see
11
+ [containerplatforms-1.8.17.md](containerplatforms-1.8.17.md)) and the e2ugh
12
+ lineage published all four architectures for the virtual-hardware engine
13
+ (`publish ghcr vhe`). One product, one registry, one architecture surface:
14
+ the s390x leg joins the node engine from the e2ugh side of the family.
15
+
16
+ ## Platform matrix
17
+
18
+ `linux/amd64` stays because it is the primary GitHub runner architecture and
19
+ the local smoke-test platform. `linux/arm64`, `linux/ppc64le` and
20
+ `linux/s390x` stay (or join) because the vhe engine of the same repository
21
+ already builds, publishes and verifies those architectures under QEMU
22
+ emulation - the publish ghcr vhe lane proves the build path - and the
23
+ node-engine build is a strict subset of that work (npm tooling, no mesa,
24
+ no qemu compilation).[1] [2]
25
+
26
+ `linux/arm/v7` and `linux/386` remain deferred because no inspected Node 26
27
+ base manifest exposes them. `windows/amd64` remains deferred (see the 1.8.17
28
+ decision): the Dockerfile uses Debian Linux stages and a Windows container
29
+ needs a Windows-specific base image, runner and smoke tests. `unknown/*`
30
+ remains rejected: OCI `unknown` descriptors are not a runnable target and
31
+ must not be advertised as a Saddle container platform.
32
+
33
+ ## Base image prerequisite (the s390x gap of the bookworm-slim variant)
34
+
35
+ The current node-engine stages build `FROM node:26.8.1-bookworm-slim`. The
36
+ manifest index of that tag (inspected through the Docker Hub registry API on
37
+ 2026-09-06, the same view `docker manifest inspect` reads) exposes exactly
38
+ `linux/amd64`, `linux/arm64` and `linux/ppc64le` - the bookworm-slim variant
39
+ does not publish an s390x entry. The Node 26 tags that DO carry s390x are
40
+ the default-distro (Debian trixie) variants: `node:26.8.1` and
41
+ `node:26.8.1-slim`. The four-arch publication therefore requires the
42
+ `saddle-build` and `saddle-runtime` FROM lines of the one container file to
43
+ move to a trixie-based variant (for example `node:26.8.1-slim`, keeping the
44
+ slim profile) before the first 2.1.0 publish run; until that base swap
45
+ lands, the buildx s390x leg cannot resolve its base manifest and the publish
46
+ job fails at the platform-resolution step. That Dockerfile change belongs to
47
+ the same 2.1.0 wave as this decision document (it is recorded here because
48
+ the container file is not part of this workflow-restoration change set).
49
+
50
+ ## Workflow design
51
+
52
+ The `publish ghcr` workflow registers QEMU (arm64, ppc64le, s390x emulation)
53
+ before Buildx, scans a loadable `linux/amd64` image (GitHub-hosted runners
54
+ cannot load a multi-platform image into the default local image store, so
55
+ the scan build stays single-platform while the publication is pushed
56
+ directly to GHCR), pushes all four Linux variants through one Buildx
57
+ invocation, and verifies the registry manifest index for the four
58
+ architectures before the amd64 label and CLI smoke test.[2] The publish lane
59
+ also carries the restored idempotency gates: the resolve job (tag ==
60
+ package.json == published release, plus the e2ugh "already shipped"
61
+ tag/HEAD guard) so a duplicate release firing no-ops instead of repushing.
62
+
63
+ ## Publication claims
64
+
65
+ The version 2.1.0 release notes and registry documentation may claim only
66
+ the four verified Linux variants after the pushed image index is inspected.
67
+ They must not claim Windows support, an `unknown` platform, or a universal
68
+ OS image.
69
+
70
+ ## References
71
+
72
+ [1]: https://docs.docker.com/build/building/multi-platform/ "Docker multi-platform builds"
73
+ [2]: https://docs.docker.com/build/ci/github-actions/multi-platform/ "Multi-platform image with GitHub Actions"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/docs/extension.md CHANGED
File without changes
File without changes
File without changes
package/docs/gapmatrix.md CHANGED
File without changes
package/docs/hardware.md CHANGED
File without changes
File without changes
File without changes
@@ -0,0 +1,54 @@
1
+ {
2
+ "version": 1,
3
+ "session": {
4
+ "id": "examplesession-0001",
5
+ "browser": "brave",
6
+ "seed": "examplesession-seed-0001"
7
+ },
8
+ "events": [
9
+ {
10
+ "t": 140,
11
+ "type": "move",
12
+ "x": 120,
13
+ "y": 90
14
+ },
15
+ {
16
+ "t": 300,
17
+ "type": "move",
18
+ "x": 180,
19
+ "y": 140
20
+ },
21
+ {
22
+ "t": 480,
23
+ "type": "click",
24
+ "x": 180,
25
+ "y": 140
26
+ },
27
+ {
28
+ "t": 680,
29
+ "type": "type",
30
+ "key": "k"
31
+ },
32
+ {
33
+ "t": 900,
34
+ "type": "move",
35
+ "x": 240,
36
+ "y": 200
37
+ },
38
+ {
39
+ "t": 1140,
40
+ "type": "click",
41
+ "x": 240,
42
+ "y": 200
43
+ },
44
+ {
45
+ "t": 1400,
46
+ "type": "scroll",
47
+ "dy": 320
48
+ }
49
+ ],
50
+ "captcha": {
51
+ "kind": "hcaptcha",
52
+ "passed": true
53
+ }
54
+ }
File without changes
File without changes
package/docs/modes.md CHANGED
File without changes
@@ -0,0 +1,38 @@
1
+ # Saddle native wrappers (generated doctrine)
2
+
3
+ The native wrappers — Android, iOS and desktop — are **generated on the CI runners and never committed**. The repository carries only the conversion configs and the icon source; the Gradle/Xcode/Rust envelopes are 100% regenerable toolchain output (audited in the 2.1.0 wave: `web/android` and `web/ios` were stock Capacitor templates, and the former `web/desktop` Rust files were 12 lines of Tauri boilerplate).
4
+
5
+ ## Doctrine
6
+
7
+ - **Generated on the runners, never committed**: the mobile workflows run `npx cap add android` / `npx cap add ios` into `build/native/` (gitignored); the desktop workflow scaffolds the Tauri Rust envelope (Cargo.toml, main.rs, lib.rs, build.rs) via heredoc into `build/native/desktop`. The historical templates remain recoverable from git history.
8
+ - **Single icon source**: `web/icon.svg` is the one source of every native icon family. Runners derive the Android mipmaps/splashs, the iOS AppIcon set and the Tauri bundle icons from it (`npx cap assets` equivalents and `npx --yes @tauri-apps/cli@2.11.4 icon web/icon.svg --output build/native/desktop/icons`).
9
+ - **Versions injected via `SADDLE_VERSION` env**: the workflows patch the generated `tauri.conf.json` copy, the Cargo manifest, the Gradle config and the iOS project with the resolved release version at build time — no committed file carries a stale native version.
10
+ - **One conversion config pair**: `web/capacitor.config.ts` (the web root, where the Capacitor CLI resolves it: `webDir` = `dist/public`, `android.path`/`ios.path` = `../build/native/{android,ios}` at the repository root) and `tauri.conf.json` (the repository root, `frontendDist` = `web/dist/public`, `bundle.icon` relative to the scaffold directory where the runner copies this config).
11
+
12
+ ## Android surface (from the retired `web/android/README.md`)
13
+
14
+ The Android surface is a Capacitor conversion target for the shared Saddle web application. The TypeScript library remains the source of engine logic, while the compiled `web/dist/public` directory supplies the WebView payload. The generated project owns application metadata, Gradle configuration, resources and signing hooks only. The workflow runs `npm run web:build:pages`, `npx cap sync android`, regenerates the Saddle icon family from `web/icon.svg` and executes Gradle release tasks. Release builds enable R8 code shrinking and resource shrinking. A production keystore is never committed; `ANDROID_KEY_BASE64`, `ANDROID_KEY_ALIAS`, `ANDROID_STORE_PASSWORD` and `ANDROID_KEY_PASSWORD` are repository secret contracts. A manual test run may opt into a clearly labeled CI test key, but that output is not a trusted store artifact. The public artifact contract is version-derived and uses dotted lowercase names such as `saddle.apk.<version>.apk` and `saddle.aab.<version>.aab`; the release manifest records the signing status and the workflow verifies the APK and AAB signatures before upload.
15
+
16
+ ## iOS surface (from the retired `web/ios/README.md`)
17
+
18
+ The iOS surface is a Capacitor conversion target for the shared Saddle web application. The TypeScript library and the compiled `web/dist/public` directory remain authoritative; the generated Xcode project owns only platform metadata, WebView hosting, entitlements and caller-provided signing configuration. The workflow runs on macOS, synchronizes the web output with `npx cap sync ios` and builds an IPA only when Apple certificates, provisioning profiles and export settings are explicitly configured. No signing material is stored in the repository, and an unsigned or unprovisioned build is never described as App Store ready. The public artifact contract is version-derived and uses the dotted lowercase pattern `saddle.ipa.<version>.ipa`.
19
+
20
+ ## Desktop surface (from the retired `web/desktop/README.md`)
21
+
22
+ The desktop surface is the Saddle browser application: one Tauri application wrapping the `web/` build. Windows, Linux and macOS use the same web assets, compiled library contracts, window policy and release version; platform differences are limited to native WebView integration, installer format and caller-owned signing. The Rust entrypoint, Cargo manifest and Tauri configuration are scaffolded by the runner (heredoc) — the frontend is `web/dist/public`, generated by `npm run web:build:pages`; the shell never copies or reimplements React routes, storage logic or engine logic. Local regeneration commands:
23
+
24
+ ```bash
25
+ npm ci
26
+ mkdir -p build/native/desktop && cd build/native/desktop
27
+ # heredoc Cargo.toml / main.rs / lib.rs / build.rs here (as the workflow does)
28
+ npx --yes @tauri-apps/cli@2.11.4 icon ../../web/icon.svg --output icons
29
+ cp ../../../tauri.conf.json .
30
+ npx --yes @tauri-apps/cli@2.11.4 dev
31
+ npx --yes @tauri-apps/cli@2.11.4 build --ci --no-sign --bundles deb,rpm,appimage
32
+ ```
33
+
34
+ The release workflow runs the native command on the matching GitHub-hosted runner, attaches only files that were actually generated and renames them to `saddle.browser.<version>.<format>`. Signing, notarization, Microsoft Store submission, Snap publication, Flatpak publication and Apple App Store submission require caller-owned credentials and are not embedded in this repository.
35
+
36
+ ## Weight removed in the 2.1.0 flatten (shadcn kit pruning, rule 98)
37
+
38
+ The static template kit `web/components/ui/` carried 50 files; only the four referenced by the live React tree survived as loose files at the web root (`button.tsx`, `card.tsx`, `tooltip.tsx`, `sonner.tsx`). The 46 unreferenced template components were deleted as dead weight (OAuth-portal template, never imported by any live page): accordion, alert, alert-dialog, aspect-ratio, avatar, badge, breadcrumb, button-group, calendar, carousel, chart, checkbox, collapsible, command, context-menu, dialog, drawer, dropdown-menu, empty, field, form, hover-card, input, input-group, input-otp, item, kbd, label, menubar, navigation-menu, pagination, popover, progress, radio-group, resizable, scroll-area, select, separator, sheet, sidebar, skeleton, slider, spinner, switch, table, tabs, textarea, toggle, toggle-group. `web/components.json` (zero readers among tests and source) and the whole `web/hooks/` folder (useMobile/useComposition/usePersistFn — imported only by the pruned kit and the dead `Map.tsx`) were deleted with it.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes